package org.musicguardian.gui;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.structuremergeviewer.DiffTreeViewer;
import org.eclipse.compare.structuremergeviewer.StructureDiffViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.swt.widgets.TreeColumn;
import org.musicguardian.core.Core;
import org.musicguardian.core.model.Album;
import org.musicguardian.core.model.Artist;
import org.musicguardian.core.model.Library;
import org.musicguardian.core.model.Model;

public class NavigationView extends ViewPart {
	public static final String ID = "org.musicguardian.gui.navigationView"; //$NON-NLS-1$

	private DiffTreeViewer viewer;

	class TreeObject {
		private String name;

		private TreeParent parent;

		public TreeObject(String name) {
			this.name = name;
		}

		public String getName() {
			return name;
		}

		public void setParent(TreeParent parent) {
			this.parent = parent;
		}

		public TreeParent getParent() {
			return parent;
		}

		public String toString() {
			return getName();
		}
	}

	class TreeParent extends TreeObject {
		private ArrayList children;

		public TreeParent(String name) {
			super(name);
			children = new ArrayList();
		}

		public void addChild(TreeObject child) {
			children.add(child);
			child.setParent(this);
		}

		public void removeChild(TreeObject child) {
			children.remove(child);
			child.setParent(null);
		}

		public TreeObject[] getChildren() {
			return (TreeObject[]) children.toArray(new TreeObject[children
					.size()]);
		}

		public boolean hasChildren() {
			return children.size() > 0;
		}
	}

	class ViewContentProvider implements IStructuredContentProvider,
			ITreeContentProvider {

		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
		}

		public void dispose() {
		}

		public Object[] getElements(Object parent) {
			return getChildren(parent);
		}

		public Object getParent(Object child) {
			if (child instanceof TreeObject) {
				return ((TreeObject) child).getParent();
			}
			return null;
		}

		public Object[] getChildren(Object parent) {
			if (parent instanceof TreeParent) {
				return ((TreeParent) parent).getChildren();
			}
			return new Object[0];
		}

		public boolean hasChildren(Object parent) {
			if (parent instanceof TreeParent)
				return ((TreeParent) parent).hasChildren();
			return false;
		}
	}

	class ViewLabelProvider extends LabelProvider {

		public String getText(Object obj) {
			return obj.toString();
		}

		public Image getImage(Object obj) {
			String imageKey = ISharedImages.IMG_OBJ_ELEMENT;
			if (obj instanceof TreeParent)
				imageKey = ISharedImages.IMG_OBJ_FOLDER;
			return PlatformUI.getWorkbench().getSharedImages().getImage(
					imageKey);
		}
	}


	private TreeObject createTreeModel() {
		TreeParent root = new TreeParent(""); //$NON-NLS-1$
		Model model = Core.getInstance().getModel();
		for (Iterator<Library> iterLibraries = model.getLocalLibraries().iterator(); iterLibraries
				.hasNext();) {
			Library library = iterLibraries.next();
			TreeParent libraryTreeParent = new TreeParent(library.getName());
			for (Iterator<Artist> iterArtists = library.getArtists().iterator(); iterArtists
					.hasNext();) {
				Artist artist = iterArtists.next();
				TreeParent artistTreeParent = new TreeParent(artist.getName());
				for (Iterator<Album> iterAlbums = artist.getAlbums().iterator(); iterAlbums.hasNext();) {
					Album album = iterAlbums.next();
					artistTreeParent.addChild(new TreeObject(album.getName()));
				}
				libraryTreeParent.addChild(artistTreeParent);
			}
			root.addChild(libraryTreeParent);
		}

		return root;
	}

	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {
//		viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
//				| SWT.BORDER);
		viewer = new DiffTreeViewer(parent, new CompareConfiguration());
		viewer.setContentProvider(new ViewContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());
//		TreeColumn treeColumn1 = new TreeColumn(viewer.getTree(), SWT.NONE);
//		treeColumn1.setWidth(60);
//		treeColumn1.setText(Messages.NavigationView_2);
//		TreeColumn treeColumn2 = new TreeColumn(viewer.getTree(), SWT.NONE);
//		treeColumn2.setWidth(60);
//		treeColumn2.setText(Messages.NavigationView_3);
		viewer.getTree().setHeaderVisible(true);
		viewer.getTree().setLinesVisible(true);
		viewer.addDoubleClickListener(new IDoubleClickListener(){

			public void doubleClick(DoubleClickEvent event) {
				TreeSelection selection = (TreeSelection) event.getSelection();
				Object firstElement = selection.getFirstElement();
				if( !(firstElement instanceof TreeParent)){
					if( firstElement instanceof TreeObject){
						System.out.println(firstElement.toString());
					}
				}
			}
			
		});
		update();
	}

	public void update() {
		viewer.setInput(createTreeModel());
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getControl().setFocus();
	}
}